﻿
namespace Behemoth.SharePoint.Services.WebServices {

    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Text;
    using System.Xml;

    using System.Linq;
    using System.Xml.Linq;

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Utilities;

    using Behemoth.Xml.Linq;
    using Behemoth.SharePoint;
    using Behemoth.SharePoint.Configuration;
    using Behemoth.SharePoint.Logging;

    using WebsService;

    /// <summary>
    /// Creates and consumes "old school" SharePoint web services.
    /// </summary>
    public class SPWebServicesClientFactory {

        internal const string WEBS_ASMX_PATH_SUFFIX = "/_vti_bin/Webs.asmx";

        public static Webs CreateWebsSvcInstance(SPWeb web) {
            Webs websWebsService = new Webs();
            websWebsService.Url = web.Url + WEBS_ASMX_PATH_SUFFIX;
            websWebsService.Credentials = System.Net.CredentialCache.DefaultCredentials; // myCred;
            return websWebsService;
        }

        #region Content Types

        [Obsolete("If possible use System.Xml.Linq and XElement queries instead.")]
        [SuppressMessage("Microsoft.Design", "CA1041:ProvideObsoleteAttributeMessage", Justification = "This method has also been marked as obsolete.")]
        public static XmlDocument GetContentTypes(SPWeb web) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode ctXml = websWebsService.GetContentTypes();
            return SPFeatureXmlTools.CreateCleanXmlDocument(ctXml);
        }
        [Obsolete("If possible use System.Xml.Linq and XElement queries instead.")]
        [SuppressMessage("Microsoft.Design", "CA1041:ProvideObsoleteAttributeMessage", Justification = "This method has also been marked as obsolete.")]
        public static XmlDocument GetContentType(SPWeb web, string cTypeID) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode ctXml = websWebsService.GetContentType(cTypeID);
            return SPFeatureXmlTools.CreateCleanXmlDocument(ctXml);
        }
        public static XmlNode UpdateContentType(SPWeb web, string cTypeID, XmlNode cTypeProperties, XmlNode newFields, XmlNode updateFields, XmlNode deleteFields) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode result = websWebsService.UpdateContentType(cTypeID, cTypeProperties, newFields, updateFields, deleteFields);
            return result;
        }

        public static List<XElement> XGetContentTypes(SPWeb web) {
            XElement ctXml = XGetContentTypesCollection(web);
            List<XElement> cTypes = ctXml.GetAllElementsOfType("ContentType");
            return cTypes;
        }
        public static XElement XGetContentTypesCollection(SPWeb web) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode node = websWebsService.GetContentTypes();
            XElement ctXml = node.GetXElement();
            if (ctXml.Name.LocalName != "ContentTypes")
                throw new Exception("Was expecting an XML element <ContentType />.");
            return ctXml;
        }
        public static XElement XGetContentType(SPWeb web, string cTypeID) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode node = websWebsService.GetContentType(cTypeID);
            XElement ctXml = node.GetXElement();
            if (ctXml.Name.LocalName != "ContentType")
                throw new Exception("Was expecting an XML element <ContentType />.");
            return ctXml;
        }
        public static XElement XUpdateContentType(SPWeb web, string cTypeID, XElement cTypeProperties, XElement newFields, XElement updateFields, XElement deleteFields) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode node = websWebsService.UpdateContentType(
                cTypeID,
                (cTypeProperties == null) ? null : cTypeProperties.GetXmlNode(),
                (newFields == null) ? null : newFields.GetXmlNode(),
                (updateFields == null) ? null : updateFields.GetXmlNode(),
                (deleteFields == null) ? null : deleteFields.GetXmlNode()
            );
            XElement result = node.GetXElement();
            //if (ctXml.Name.LocalName != "ContentType")
            //    throw new Exception("Was expecting an XML element <ContentType />.");
            return result;
        }

        #endregion

        #region Site Columns

        /// <summary>
        /// Gets the xml from GetColumns web method and cleans it up to prepare for an update.
        /// </summary>
        /// <param name="websWebsService"></param>
        /// <param name="web"></param>
        /// <returns></returns>
        [Obsolete("If possible use System.Xml.Linq and XElement queries instead.")]
        [SuppressMessage("Microsoft.Design", "CA1041:ProvideObsoleteAttributeMessage", Justification = "This method has also been marked as obsolete.")]
        public static XmlDocument GetColumns(SPWeb web) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode columnXml = websWebsService.GetColumns();
            return SPFeatureXmlTools.CreateCleanXmlDocument(columnXml);
        }

        public static XmlNode UpdateColumns(SPWeb web, XmlNode newColumns, XmlNode updateColumns, XmlNode deleteColumns) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode result = websWebsService.UpdateColumns(newColumns, updateColumns, deleteColumns);
            return result;
        }


        /// <summary>
        /// Gets the xml from GetColumns web method and cleans it up to prepare for an update.
        /// </summary>
        /// <param name="websWebsService"></param>
        /// <param name="web"></param>
        /// <returns></returns>
        public static XElement XGetColumns(SPWeb web) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode node = websWebsService.GetColumns();
            XElement columnXml = node.GetXElement();
            // TODO check type
            return columnXml;
        }

        public static XElement XUpdateColumns(SPWeb web, XElement newColumns, XElement updateColumns, XElement deleteColumns) {
            Webs websWebsService = CreateWebsSvcInstance(web);
            XmlNode node = websWebsService.UpdateColumns(
                (newColumns == null) ? null : newColumns.GetXmlNode(),
                (updateColumns == null) ? null : updateColumns.GetXmlNode(),
                (deleteColumns == null) ? null : deleteColumns.GetXmlNode()
            );
            XElement result = node.GetXElement();
            // TODO check type
            return result;
        }

        #endregion

    }
}

